package com.weilan.ark3.read;

import com.weilan.ark3.buffer.DataArray;
import com.weilan.ark3.buffer.MsgQueue;
import com.weilan.ark3.serial.SerialPortCom3Service;
import com.weilan.ark3.service.ControlRtuService;
import com.weilan.ark3.tcp.TcpMaster;
import com.weilan.ark3.tcp.TcpSlave;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import static com.weilan.ark3.buffer.OverallSituation.*;
import static com.weilan.ark3.common.GlobalParam.cacheFaultKey;

@Component
public class ThreadMannger implements ApplicationRunner {

    @Autowired
    private ReadRtuData loadRtuComponent;

    @Autowired
    private COM2ReadData com2ReadData;
    @Autowired
    private SerialPortCom3Service serialPortCom3Service;
    @Autowired
    private ControlRtuService rtuService;
    @Autowired
    private COM3ReadData com3ReadData;
    Logger tcpServer = LoggerFactory.getLogger("TCPServer_Appender");

    private Thread workerThread1;
    private Thread workerThread2;
    private Thread workerThread3;
    private Thread workerThread4;
    private Thread workerThread5;
    private Thread workerThread6;
    private Thread workerThread8;
    private Thread workerThread9;
    private Map<Integer, Thread> TCPThreads = new HashMap<>();

    @Override
    public void run(ApplicationArguments args) throws Exception {
        // 创建ScheduledExecutorService
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
        startWorkerThread4();//创建Tcp从站
        // 初次启动工作线程
        if (com1State == 1) {
            startWorkerThread1();//读取COM1
            rtuService.readModBusRTUData("COM1");
            rtuService.readModBusRTUData2("COM1");

        }
        if (tcpState == 1) {
            TcpMaster.init(arkDeviceNumber);
            rtuService.readModBusTCPData("TCP");
            rtuService.readModBusTCP2Data("TCP");

        }
        if (com2State == 1) {
            startWorkerThread5();//读取和插入COM2
        }
        if (com3State == 1) {
            startWorkerThread6();//读取和插入COM3
        }
        // 定期检查线程状态
        scheduler.scheduleAtFixedRate(() -> {
            checkAndRestartWorkerThread("tcp从站", workerThread4, this::startWorkerThread4);
            if (com1State == 1) {
                checkAndRestartWorkerThread("读取COM1", workerThread1, this::startWorkerThread1);
            }
            if (com2State == 1) {
                checkAndRestartWorkerThread("COM2", workerThread5, this::startWorkerThread5);
            }
            if (com3State == 1) {
                checkAndRestartWorkerThread("COM3", workerThread6, this::startWorkerThread6);
            }
        }, 0, 15, TimeUnit.SECONDS); // 检查间隔为10秒
        if (tcpState == 1) {
            startThreads(arkDeviceNumber);//启动Tcp主站线程
            startMonitorThread();//启动监控线程
        }
        Message.Message_Init(com1MessgeRank1,com1MessgeRank2,tcpMessgeRank1,tcpMessgeRank2);
    }


    // 检查并重新启动线程的方法
    private void checkAndRestartWorkerThread(String threadName, Thread thread, Runnable startThreadMethod) {
        if (thread == null || !thread.isAlive()) {
            tcpServer.info(threadName + "死亡");
            startThreadMethod.run();
        } else {
            tcpServer.info(threadName + "运行");
        }
    }

    // 读取COM1
    private void startWorkerThread1() {
        workerThread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                //读取UC数据
                //COM1
                loadRtuComponent.ReadRtuData();
            }
        }, "读取COM1");
        workerThread1.start();
    }


    // 创建TCP从站
    private void startWorkerThread4() {
        workerThread4 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = tcpSlaveStartId; i < arkDeviceNumber + tcpSlaveStartId; i++) {
                    slaveSet.add(i);
                }
                if (ACU == 1) {
                    for (int j = acuStartId; j < acuDeviceNumber + acuStartId; j++) {
                        slaveSet.add(j);
                    }
                }
                slaveSet.add(1);
                for (Integer slaveId : slaveSet) {
                    DataArray.slaveDataMap.put(slaveId, new short[20000]);
                    DataArray.dataToCacheCMD.put(slaveId, new String[cacheFaultKey.length]);
                }
                TcpSlave.createModbusSlave(slaveSet);
            }
        }, "tcp从站");
        workerThread4.start();
    }

    //读取和插入COM2
    private void startWorkerThread5() {
        workerThread5 = new Thread(new Runnable() {
            @Override
            public void run() {
                rtuService.readModBusRTUDataCOM2("COM2");
                com2ReadData.ReadRtuData();
            }
        }, "COM2");
        workerThread5.start();
    }

    //读取和插入COM3
    private void startWorkerThread6() {
        workerThread6 = new Thread(new Runnable() {
            @Override
            public void run() {
                rtuService.readModBusRTUDataPV("COM3");
                com3ReadData.ReadCom3Data();
            }
        }, "COM3");
        workerThread6.start();
    }


    public void startThreads(int numberOfThreads) {
        for (int i = 1; i <= numberOfThreads; i++) {
            startTcpThread(i);
        }
    }

    private void startTcpThread(int threadNumber) {
        String threadName = "tcp主站" + threadNumber;
        Runnable task = () -> {
            try {
                switch (threadNumber) {
                    case 1:
                        loadRtuComponent.ReadTCP1Data(15 + threadNumber);
                        break;
                    case 2:
                        loadRtuComponent.ReadTCP2Data(15 + threadNumber);
                        break;
                    case 3:
                        loadRtuComponent.ReadTCP3Data(15 + threadNumber);
                        break;
                    case 4:
                        loadRtuComponent.ReadTCP4Data(15 + threadNumber);
                        break;
                    case 5:
                        loadRtuComponent.ReadTCP5Data(15 + threadNumber);
                        break;
                    case 6:
                        loadRtuComponent.ReadTCP6Data(15 + threadNumber);
                        break;
                    default:
                        throw new IllegalArgumentException("Invalid thread number: " + threadNumber);
                }
            } catch (Exception e) {
                tcpServer.info("Exception in " + threadName + ": " + e.getMessage());
            } finally {
                tcpServer.info(threadName + " 结束. 正在重启...");
                startTcpThread(threadNumber);
            }
        };

        Thread workerThread = new Thread(task, threadName);
        TCPThreads.put(threadNumber, workerThread);
        workerThread.start();
    }

    private void startMonitorThread() {
        Thread monitorThread = new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(10000); // 每5秒检查一次线程状态
                    for (Map.Entry<Integer, Thread> entry : TCPThreads.entrySet()) {
                        Thread workerThread = entry.getValue();
                        if (!workerThread.isAlive()) {
                            System.out.println(workerThread.getName() + " 已死亡，正在重启...");
                            startTcpThread(entry.getKey());
                        }
                    }
                } catch (InterruptedException e) {
                    tcpServer.info("监控线程被中断");
                    Thread.currentThread().interrupt();
                }
            }
        }, "监控线程");
        monitorThread.setDaemon(true);
        monitorThread.start();
    }
}
